// RemoveReadOnly.h
// (c) 2008, Charles Lechasseur
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "RemoveReadOnly.h"

#include <memory>
#include <string>


namespace
{
    //
    // Class ID of the RemoveReadOnly CoClass.
    //
    const CLSID CLSID_RemoveReadOnly =
        {0xC1460D32, 0x8416, 0x43EA, {0x87, 0xDB, 0xEB, 0xE9, 0x55, 0xC1, 0x3C, 0xA5}};

    //
    // ProgID of the RemoveReadOnly CoClass.
    //
    const std::string PROGID_RemoveReadOnly = "RemoveReadOnly.RemoveReadOnly";

    //
    // Description of the RemoveReadOnly CoClass.
    //
    const std::string DESCRIPTION_RemoveReadOnly
        = "Shell context menu extension to remove read-only flag from files and folders.";

}; // anonymous namespace

namespace RRO
{
// -- RemoveReadOnly class --

    //
    // Constructor.
    //
    RemoveReadOnly::RemoveReadOnly(void)
        : Object()
    {
    }

    //
    // Destructor.
    //
    RemoveReadOnly::~RemoveReadOnly(void)
    {
    }

    //
    // First method called by the shell, giving us the opportunity to populate the contextual menu.
    //
    // @param p_hMenu Handle to the contextual menu to populate.
    // @param p_FirstItemIndex Index of the first item to insert in the menu.
    // @param p_FirstCmdID First command ID available for our menu item commands.
    // @param p_LastCmdID Last command ID available for our menu item commands. The command IDs
    //                    must fall between p_FirstCmdID and p_LastCmdID.
    // @param p_Flags Flags specifying information about the context of the call. See MSDN for details.
    //
    STDMETHODIMP RemoveReadOnly::QueryContextMenu(
        HMENU p_hMenu, UINT p_FirstItemIndex,
        UINT p_FirstCmdID, UINT p_LastCmdID, UINT p_Flags)
    {
        // TODO
        return E_NOTIMPL;
    }

    //
    // Method called when one of our menu items is selected in the menu. We must handle the
    // resulting call here.
    //
    // @param p_pCommandInfo Pointer to struct containing command information.
    //
    STDMETHODIMP RemoveReadOnly::InvokeCommand(
        CMINVOKECOMMANDINFO* p_pCommandInfo)
    {
        // TODO
        return E_NOTIMPL;
    }

    //
    // Method called to get text info for a menu item that we added to the contextual menu.
    //
    // @param p_CmdId ID of the command for which text info is needed.
    // @param p_Flags Flags indicating what info is requested. See MSDN for details.
    // @param p_pReserved Reserved; unused.
    // @param p_pName Buffer where to store the text requested. If the requested info is Unicode
    //                (pFlags & GSC_UNICODE != 0), cast this to a LPWSTR to store Unicode text.
    // @param p_NameBufSize Size of the p_pName buffer, in characters.
    STDMETHODIMP RemoveReadOnly::GetCommandString(
        UINT_PTR p_CmdId, UINT p_Flags, UINT* p_pReserved,
        LPSTR p_pName, UINT p_NameBufSize)
    {
        // TODO
        return E_NOTIMPL;
    }

// -- RemoveReadOnlyFactory class --

    //
    // Constructor.
    //
    RemoveReadOnlyFactory::RemoveReadOnlyFactory(void)
        : ClassFactory(new COM::CreatorT<RemoveReadOnly>(), CLSID_RemoveReadOnly,
                       PROGID_RemoveReadOnly, COM::THREADING_MODEL_APARTMENT,
                       DESCRIPTION_RemoveReadOnly.c_str())
    {
    }

    //
    // Destructor.
    //
    RemoveReadOnlyFactory::~RemoveReadOnlyFactory(void)
    {
    }

}; // namespace RRO
